/*
 *    Copyright (c) 2018-2025, nart All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the pig4cloud.com developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: nart
 */

package com.nai365.nart.product.controller;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Console;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nai365.nart.common.core.constant.SecurityConstants;
import com.nai365.nart.common.core.util.R;
import com.nai365.nart.common.log.annotation.SysLog;
import com.nai365.nart.common.security.annotation.Inner;
import com.nai365.nart.common.security.service.NartUser;
import com.nai365.nart.common.security.util.SecurityUtils;
import com.nai365.nart.product.entity.BrandFans;
import com.nai365.nart.product.entity.SkuInfo;
import com.nai365.nart.product.entity.SpuInfo;
import com.nai365.nart.product.service.SkuInfoService;
import com.nai365.nart.product.service.SpuInfoService;
import com.nai365.nart.product.vo.SpuSaveVo;
import com.nai365.nart.search.api.feign.SearchFeignService;
import com.nai365.nart.seckill.api.feign.SeckillFeignService;
import io.swagger.annotations.ApiModelProperty;
import com.nai365.nart.common.excel.annotation.ResponseExcel;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * spu信息
 *
 * @author baogs
 * @date 2022-07-01 11:05:45
 */
@RestController
@RequiredArgsConstructor
@RequestMapping("/spuinfo")
@Api(value = "spuinfo", tags = "spu信息管理")
public class SpuInfoController {

	private final SpuInfoService spuInfoService;

	private final SearchFeignService searchFeignService;
	private final SkuInfoService skuInfoService;

	private final SeckillFeignService seckillFeignService;


	/**
	 * 分页查询
	 *
	 * @param page    分页对象
	 * @param spuInfo spu信息
	 * @return
	 */
	@ApiOperation(value = "分页查询", notes = "分页查询")
	@GetMapping("/page")
	@Inner(value = false)
	public R getSpuInfoPage(Page page, SpuInfo spuInfo) {
		return R.ok(spuInfoService.page(page, Wrappers.query(spuInfo)));
	}


	//商品上架
	///product/spuinfo/{spuId}/up
	@ApiModelProperty(value = "根据spuId上架", notes = "根据spuId上架")
	@PostMapping(value = "/{spuId}/up")
	public R spuUp(@PathVariable("spuId") Long spuId) {
		return spuInfoService.up(spuId);
	}

	@ApiModelProperty(value = "根据spuId上链", notes = "根据spuId上链")
	@PostMapping(value = "/{spuId}/up_chain")
	public R upChain(@PathVariable("spuId") Long spuId) {
		return spuInfoService.upChain(spuId);
	}

	//商品下架
	///product/spuinfo/down
	@ApiModelProperty(value = "根据spuId下架", notes = "根据spuId下架")
	@GetMapping(value = "/down")
	public R spuDown(@RequestParam("spuId") Long spuId) {
		spuInfoService.down(spuId);
		return R.ok(searchFeignService.productDown(spuId, SecurityConstants.FROM_IN));
	}


	/**
	 * 保存
	 */
	@PostMapping("/save")
	public R save(@RequestBody SpuSaveVo vo) {
		spuInfoService.savesupInfo(vo);

		return R.ok();
	}


	/**
	 * 查询最近三天需要秒杀的场次+商品
	 */
	@GetMapping(value = "/Lates3DaySession")
	@Inner(value = false)
	public R getLates3DaySession() {
		return R.ok(spuInfoService.getLates3DaySpuInfo());
	}

	/**
	 * 根据spuId查询需要上架的藏品
	 */
	@GetMapping(value = "/get_seckill_session")
	@Inner(value = false)
	public R getSeckillSession(String spuId) {
		return R.ok(spuInfoService.getSpuInfoSessions(spuId));
	}


	/**
	 * 列表
	 */
	@GetMapping("/list")
	public R list(Page page, SpuInfo spuInfo, String key) {
		return R.ok(spuInfoService.queryPageByCondtion(page, spuInfo, key));
	}

	/**
	 * 我的藏品列表
	 */
	@GetMapping("/list/my_product")
	@ApiOperation(value = "我的藏品列表", notes = "我的藏品列表")
	public R mylist(Page page) {
		Long userId = SecurityUtils.getUser().getId();
		Page page1 = skuInfoService.page(page, new QueryWrapper<SkuInfo>().select("distinct spu_id ,update_time").lambda()
				.eq(SkuInfo::getOwnerId, userId)
				.orderByDesc(SkuInfo::getUpdateTime)
		);

		List<SkuInfo> records = page1.getRecords();
		if (CollectionUtil.isNotEmpty(records)) {


			List<Long> ids = records.parallelStream().map(item -> item.getSpuId()).collect(Collectors.toList());

			List<SpuInfo> list = spuInfoService.list(new LambdaQueryWrapper<SpuInfo>().in(SpuInfo::getId, ids));

			final Map<String, String> avgMap = new HashMap<String, String>();
			R r = searchFeignService.listSearchSpusStatInner(ids, SecurityConstants.FROM_IN);
			if (r.getCode() == 0) {
				Map<String, String> parse = (Map<String, String>) JSONUtil.parse(r.getData());
				avgMap.putAll(parse);
			}

			List<SpuInfo> collect1 = list.parallelStream().map(item ->
			{
				Long id1 = item.getId();
				List<SkuInfo> list1 = skuInfoService.list(new LambdaQueryWrapper<SkuInfo>().eq(SkuInfo::getSpuId, id1).eq(SkuInfo::getOwnerId, userId).orderByDesc(SkuInfo::getUpdateTime));
				item.setSkuInfoList(list1);
				item.setAvgPrice(String.valueOf(avgMap.get(item.getId() + "")));
				return item;
			}).collect(Collectors.toList());

			page1.setRecords(collect1);

			return R.ok(page1);
		} else {
			return R.failed("藏品为空");
		}
	}

	@GetMapping("/search/name")
	public R<Page<SpuInfo>> listByName(Page<SpuInfo> page, String name) {
		LambdaQueryWrapper<SpuInfo> queryWrapper = Wrappers.lambdaQuery();
		if (!StringUtils.isEmpty(name)) {
			queryWrapper.like(SpuInfo::getSpuName, name);
		}
		return R.ok(spuInfoService.page(page, queryWrapper));
	}

	@ApiOperation(value = "通过id查询", notes = "通过id查询")
	@GetMapping("/list/ids")
	@Inner
	public R<List<SpuInfo>> getByIds(@RequestParam("idList") List<Long> idList) {
		List<SpuInfo> result = new ArrayList<>();
		if (!ObjectUtils.isEmpty(idList)) {
			result = spuInfoService.listByIds(idList);
		}
		return R.ok(result);
	}


	/**
	 * 查询已上链藏品
	 */
	@GetMapping("/list/chain")
	public R<Page<SpuInfo>> findChainByName(Page<SpuInfo> page, String name) {
		LambdaQueryWrapper<SpuInfo> queryWrapper = Wrappers.lambdaQuery();
		queryWrapper.eq(SpuInfo::getIsChain, 1);
		if (!StringUtils.isEmpty(name)) {
			queryWrapper.and((wrapper) -> {
				wrapper.like(SpuInfo::getSpuName, name);
			});
		}
		return R.ok(spuInfoService.page(page, queryWrapper));
	}

	/**
	 * 查询合成目标藏品
	 *
	 * @param page 分页参数
	 * @param name 藏品名称
	 * @return 分页对象
	 */
	@GetMapping("/list/compound")
	public R<Page<SpuInfo>> findCompoundByName(Page<SpuInfo> page, String name) {
		LambdaQueryWrapper<SpuInfo> queryWrapper = Wrappers.lambdaQuery();
		queryWrapper.eq(SpuInfo::getIsChain, 1);
		if (!StringUtils.isEmpty(name)) {
			queryWrapper.and((wrapper) -> {
				wrapper.like(SpuInfo::getSpuName, name);
			});
		}
		return R.ok(spuInfoService.page(page, queryWrapper));
	}


	/**
	 * 通过id查询spu信息
	 *
	 * @param id id
	 * @return R
	 */
	@ApiOperation(value = "通过id查询", notes = "通过id查询,type传2为二级市场详情")
	@GetMapping("/{id}")
	@Inner(value = false)
	public R getById(@PathVariable("id") Long id, Integer type) {
		type = type == null ? 1 : type;
		SpuInfo byId = spuInfoService.getById(id);
		if (type != null && type == 2) {
			R skuStat = searchFeignService.getSkuStat(id, type, SecurityConstants.FROM_IN);
			JSONObject spuInfo = JSONUtil.parseObj(byId);
			if (skuStat.getCode() == 0) {
				JSONObject stats = JSONUtil.parseObj(skuStat.getData());
				if (stats != null) {
					JSONObject stats1 = (JSONObject) stats.get("stats");
					if (stats1 != null) {
						spuInfo.putOpt("lowerPrice", stats1.get("min"));
						spuInfo.putOpt("currSellQuantity", stats1.get("count"));
					}
				}
			}
			return R.ok(spuInfo);
		} else {
			handlerStatus(byId);
			return R.ok(byId);
		}
	}

	/**
	 * 处理藏品状态
	 **/
	private void handlerStatus(SpuInfo byId) {
		int status = 0;
		R r = seckillFeignService.skuCount(byId.getId() + "", SecurityConstants.FROM_IN);
		if (r.getCode() == 0 && r.getData() != null) {
			Integer count = Integer.parseInt(r.getData().toString());
			if (count > 0) {
				status = 7;
			}
		}

		Integer sellPattern = byId.getSellPattern();
		LocalDateTime prioritySellBeginTime = byId.getPrioritySellBeginTime();
		LocalDateTime prioritySellEndTime = byId.getPrioritySellEndTime();
		LocalDateTime drawBeginTime = byId.getDrawBeginTime();
		LocalDateTime drawEndTime = byId.getDrawEndTime();
		LocalDateTime now = LocalDateTime.now();
		boolean before = now.isBefore(prioritySellBeginTime);
		if (before) {
			status = 1;
		} else if (now.isBefore(prioritySellEndTime) && now.isAfter(prioritySellBeginTime)) {
			status = 2;
		} else if (now.isBefore(drawBeginTime) && now.isAfter(prioritySellEndTime)) {
			status = 3;
		} else if (now.isBefore(drawEndTime) && now.isAfter(drawBeginTime)) {
			status = 4;
		} else if (now.isBefore(drawEndTime.plusMinutes(15)) && now.isAfter(drawEndTime)) {
			status = 5;
		} else if (now.isAfter(drawEndTime.plusMinutes(15))) {
			status = 6;
		}

		if (sellPattern == 1 && (status == 1 || status == 2 || status == 3 || status == 6 || status == 7)) {
			byId.setStatus(status);
		} else if (sellPattern == 3 && (status == 1 || status == 6 || status == 7)) {
			byId.setStatus(status);
		} else {
			byId.setStatus(status);
		}
	}

	/**
	 * 新增spu信息
	 *
	 * @param spuInfo spu信息
	 * @return R
	 */
	@ApiOperation(value = "新增spu信息", notes = "新增spu信息")
	@SysLog("新增spu信息")
	@PostMapping
	public R save(@RequestBody SpuInfo spuInfo) {
		return R.ok(spuInfoService.save(spuInfo));
	}

	/**
	 * 修改spu信息
	 *
	 * @param spuInfo spu信息
	 * @return R
	 */
	@ApiOperation(value = "修改spu信息", notes = "修改spu信息")
	@SysLog("修改spu信息")
	@PutMapping
	public R updateById(@RequestBody SpuInfo spuInfo) {
		return R.ok(spuInfoService.updateById(spuInfo));
	}

	/**
	 * 通过id删除spu信息
	 *
	 * @param id id
	 * @return R
	 */
	@ApiOperation(value = "通过id删除spu信息", notes = "通过id删除spu信息")
	@SysLog("通过id删除spu信息")
	@DeleteMapping("/{id}")
	public R removeById(@PathVariable Long id) {
		return R.ok(spuInfoService.removeById(id));
	}


	/**
	 * 导出excel 表格
	 *
	 * @param spuInfo 查询条件
	 * @return excel 文件流
	 */
	@ResponseExcel
	@GetMapping("/export")
	public List<SpuInfo> export(SpuInfo spuInfo) {
		return spuInfoService.list(Wrappers.query(spuInfo));
	}


	/**
	 * 根据SkuId查询SPU信息
	 */
	@GetMapping("/skuId/{skuId}")
	@Inner
	public R getSpuInfoBySkuId(@PathVariable("skuId") Long id) {

		return R.ok(spuInfoService.getBySkuId(id));
	}

	/**
	 * 信息
	 */
	@GetMapping("/info/{id}")
	public R info(@PathVariable("id") Long id) {
		SpuInfo spuInfo = spuInfoService.getById(id);
		return R.ok(spuInfo);
	}


}
